Repository navigation
feat(service-automation): the automation engine holds a connector instance by its package and name, and a dispatch addresses the one its caller's name resolves to - #33281
Conversation
…tance by its package and name, and a dispatch addresses the one its caller's name resolves to The engine's connectors are held by (package, name); a bare-name read answers the one instance, never one of two. connector_action resolves the instance for the calling flow's package and reads its handler, effect and inputSchema from it. The reconcile registers each declarative instance with its package and as the sole instance of its name, re-registers it when its package changes, and drops it by name. The OAuth2 grant handle asks its package on every read, and serves a token only for the connection row it was obtained for. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
|
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT Contract-review-claim: session_01L9qibzKCovWpJoMZD6U3NT · head 17ac714 · 2026-11-14T15:29Z An isolated reviewer sub-agent of the card thread reviews this head at |
📓 Docs Drift CheckThis PR changes 1 package(s): 20 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 11 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 11 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 4d70ee9f7dc018e3dd45b425631f7429478d9920 && git checkout 4d70ee9f7dc018e3dd45b425631f7429478d9920
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87330e8959070c0e0a18d1a48981c981642926b7 bcda1d64655b45104187408d34066eb268cd3bf9 && git checkout -B drift-repro 87330e8959070c0e0a18d1a48981c981642926b7 && git merge --no-ff bcda1d64655b45104187408d34066eb268cd3bf9
node scripts/docs-audit/affected-docs.mjs --json 87330e8959070c0e0a18d1a48981c981642926b7
|
|
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT Posted 2026-11-14T15:36Z. The brief the card thread handed its isolated reviewer sub-agent for the record below, verbatim. Contract review brief — PR #33281 @
|
|
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT Posted 2026-11-14T15:37Z. An isolated reviewer sub-agent of the card thread produced this record from the brief alone (card #31699 with all 39 comments, PR #33281's body, file list and net diff, and the check-runs on the head). Contract reviewServed-tier: ① Derived judgmentsRead: 14 files, +662 / -69, one commit on Public surface (the package exports
Answers:
Findings, all nits:
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…with no instance argument, the empty token cache after re-materialization, and every answer that moves Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
|
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx 维护者速读 · PR #33281 @
|
…ide the connector instances Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
|
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx 席位核对 · 再落地 · PR #33281 @
|
Requested by Tesla · project thread
Part of #31699
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
ConnectorInstances)。connector_action按调用方 flow 的包解析出那个实例,并从它读取处理器、effect和inputSchema。只按名字读时,只有一个实例才回答,两个时不回答,绝不挑一个。soleOfName)。因此除下面一个过渡状态外,所有派发、连接门和 HTTP 答复照旧。plugin.ts: the materializer state andgrantHandlesare keyed by instance" 这一行移到收窄兜底的 PR。原因见下文 "Moved to the narrowing PR"。packages/services/service-automation/src/connector-instances.ts、src/engine.ts(resolveConnectorInstanceFor)、src/plugin.ts(declaredInstance、期望签名里的包)、src/oauth2-grant/grant-handle.ts(每次读取时取包;令牌绑定连接行)。What changes
ConnectorInstances,engine.ts): the registered connectors are held by(package, name).connectorInstancePackagefrom 3a-ii).resolveConnectorAction,getConnectorOrigin, the degraded reads, …) answers the one instance of the name, and none when there are two.getRegisteredConnectorslists each name once;getConnectorDescriptorslists every instance.plugin-extension-api.ts):registerConnectorandregisterDegradedConnectortake an optional{ packageId, soleOfName }, andunregisterConnectortakes an optional package.soleOfName, a declarative registration drops any other declarative instance of the name. The reconcile always passes it.connector-nodes.ts,connector-input-schema.ts):connector_actionresolves itsconnectorIdfor the calling flow's package (resolveConnectorInstance). The cases:effectandinputSchemaare read from that instance.plugin.ts):declaredInstance(ctx, entry).grant-handle.ts):Moved to the narrowing PR (deviations from the file list)
grantHandlesstay keyed by name. This is the amended file list'splugin.tsline, items 1, 3 and 5. The maps in question aredesired, the materialized, degraded and credential-refusal maps, the retry bookkeeping andgrantHandles. Under the one-holder backstop the reconcile cannot hold two instances of one name, so re-keying these maps changes nothing anyone can observe until the duplicate-name refusal is lifted. It lands with that lift and with a test of two live instances. The registrations already carry the instance package, and the grant handle already reads its package per read (item 4), so the re-key is bookkeeping only. Agreed with the lane seat before coding.connector-pull.tsline). Resolving a mapping's connector for the job's package changes an answer where that name is refused, so it is decided with the narrowing.resolveConnectorInstanceFor, a resolved holder with no instance registered under it is answered by the one instance of the name. That is right only while one instance per name is kept. The narrowing PR makes itnone.ConnectorDescriptor.packageId,?package=on the connection door, and connector in the namespace-scoped type sets were already listed for the narrowing PR.Verification
flow-package-scoped-resolution.test.ts, 8 engine pins:inputSchemais read per instance;soleOfName;connector-connection-door.test.ts:connector-connection-door.test.tsalso pins that replacing the holder of an unstamped entry, leaving one holder, keeps the dispatch at 200; and the store's two-holder refusal names the uninstall remedy for a row that already names a package (feat(service-automation): the connector connection store, the connect door and the OAuth callback read and write one instance by its package and name #33218 review N4).grant-handle.test.ts:@objectstack/service-automationfull suite, rebased onmainafter feat(service-automation): the connector connection store, the connect door and the OAuth callback read and write one instance by its package and name #33218: 281 files, 3890 tests passed.tsc --noEmit, ESLint on touched files,check-engine-double-contract,tenant-audit-censusandsystem-context-censusare green.Red-line read
Run in this thread by a separate review pass (maintainer's instruction: 「你自己有fable,自己审就可以了吧?」).
mainand adapted to feat(service-automation): the connector connection store, the connect door and the OAuth callback read and write one instance by its package and name #33218's one-holder store rule (its contract review F1): the tightened answer now covers only a second holder appearing after boot, and the store's refusal for a row already naming a non-holder package names the uninstall remedy (feat(service-automation): the connector connection store, the connect door and the OAuth callback read and write one instance by its package and name #33218 review N4). This PR is opened as a draft and owes its contract review at TIER_DEFAULT from an isolated reviewer, as feat(service-automation): the connector connection store, the connect door and the OAuth callback read and write one instance by its package and name #33218 had.yes (widening)right. No surface is removed and every API change is additive. The one tightened answer is a dispatch in a transitional state that the connection door has refused since 3a-ii, and the next reconcile re-registers or tears it down.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT